$def with (a, b)

$var title: $_("Diff on %s", a.key)

$putctx("robots", "noindex,nofollow")

<div id="contentHead">

    $:macros.databarDiff()

    $if a.type.key in ["/type/edition", "/type/work", "/type/page"]:
        $ title = a.title or a.key
    $elif a.type.key in ["/type/author"]:
        $ title = a.name or a.key
    $else:
        $ title = a.key

    <h2 class="collapse"><a href="$a.key">$title</a> &rarr; Diff</h2>

    <div id="legend">
       <dl>
           <dd class="add">$_("Added")</dd>
           <dd class="mod">$_("Modified")</dd>
           <dd class="rem">$_("Removed")</dd>
           <dd class="unmod">$_("Not changed")</dd>
       </dl>
    </div>

</div>

$def display_revision(page):
    <div class="small sansserif">
        <a href="$changequery({}, v=page.revision)"><span class="uppercase"><strong>$_("Revision %d", page.revision)</strong></span></a>
        $ v = get_version(page.key, page.revision)
        $if v.author:
            <span class="brown">$_('by') <a href="$v.author.key">$v.author.displayname</a> $datestr(v.created)</span>
        $else:
            <span class="brown">$_('by Anonymous') $datestr(v.created)</span>
    </div>

$def diff_covers(p, a, b):
    $if a[p] != b[p]:
        <tr>
            <td class="diff-header-side">$p</td>
            <td class="diff-body">
                $for img in a[p]:
                    <img src="$get_coverstore_url()/b/id/$img-M.jpg"/>
            </td>
            <td class="diff-body">
                $for img in b[p]:
                    <img src="$get_coverstore_url()/b/id/$img-M.jpg"/>
            </td>
        </tr>

$def listdiff(name, a, b):
    $ diffresults = better_diff(a or [], b or [])
    <tr>
        <td class="diff-header-side" style="vertical-align: top;">$name</td>
        <td colspan="2">
        <table style="width: 100%;">
        $for key, ai, a, bi, b in diffresults:
            <tbody class="$key">
            <tr>
                <td class="diff-number">$ai</td>
                <td class='l'>$:diff_display(name, a)</td>
                <td class="diff-number">$bi</td>
                <td class='r'>$:diff_display(name, b)</td>
            </tr>
            </tbody>
        </table>
        </td>
    </tr>

$def diff_display(name, value):
    $if isinstance(value, basestring):
        $value
    $elif isinstance(value, dict):
        $value
    $else:
        $if name == "links":
            <a href="$value.url">$value.title</a>
            <span style="display: block" class="link wrap">$value.url</span>
        $elif name == "excerpts":
            <span>$value.excerpt</span>
        $elif value.key:
            <a href="$value.key">$(value.name or value.title or value.key)</a>
            <span style="display: block" class="link wrap">$value.key</span>
        $else:
            $ value = value.dict()
            $value

<div id="contentBody" class="diff">

    <table class="revisions" summary="$_('Differences')">
        <colgroup class="l"><col class="line" /><col class="content" /></colgroup>
        <colgroup class="r"><col class="line" /><col class="content" /></colgroup>
        <thead>
            <tr>
                <th></th>
                <th style="width: 40%;">$:display_revision(a)</th>
                <th style="width: 40%;">$:display_revision(b)</th>
            </tr>
        </thead>
        <tbody>

        $code:
            def find_diff(a, b, p):
                label = p
                # quick hack to display images in diff
                if p in ["covers", "photos"]:
                    return diff_covers(p, a, b)
                elif p == "table_of_contents":
                    return thingdiff("/type/text", "table_of_contents", a.get_toc_text(), b.get_toc_text())
                elif p == "title_prefix":
                    return thingdiff("/type/string", "title_prefix", a[p].strip(), b[p].strip())
                elif p == "authors":
                    label = "authors"
                    t = "/type/author"
                    ap = a.get_authors()
                    bp = b.get_authors()
                else:
                    ap = a[p]
                    bp = b[p]
                    t = get_expected_type(a, p)

                if isinstance(ap, list) or isinstance(bp, list):
                    if ap == bp:
                        return ""
                    else:
                        return listdiff(label, ap, bp)
                elif t == "/type/string":
                    if is_thing(ap):
                        ap = ap.dict()
                    if is_thing(bp):
                        bp = bp.dict()
                return thingdiff(t, label, ap, bp)

        $ diff_count = 0

        $for p in set(a.keys() + b.keys()):
            $ diff = find_diff(a, b, p)
            $if not isinstance(diff, (str, unicode)) and hasattr(diff, "next"):
                $ diff = u"".join(text for _x, text in diff)

            $if isinstance(diff, (str, unicode)):
                $ diff = diff and diff.strip()
            $if diff:
                $:diff
                $ diff_count += 1
        $if diff_count == 0:
            <tr>
                <td colspan="3" style="text-align: center;">$_("Both the revisions are identical.")</td>
            </tr>
        </tbody>
    </table>
    <div class="clearfix"></div>

</div>
